package com.itheima.app.manager;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.itheima.app.interceptor.UserHolder;
import com.itheima.app.mq.MovementMQSend;
import com.itheima.autoconfig.oss.OssTemplate;
import com.itheima.domain.db.UserInfo;
import com.itheima.domain.mongo.Comment;
import com.itheima.domain.mongo.Movement;
import com.itheima.domain.mongo.MyMovement;
import com.itheima.service.db.UserInfoService;
import com.itheima.service.mongo.CommentService;
import com.itheima.service.mongo.MovementService;
import com.itheima.util.ConstantUtil;
import com.itheima.vo.CommentVo;
import com.itheima.vo.MovementVo;
import com.itheima.vo.PageBeanVo;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Component
public class MovementManager {

    @Reference
    private MovementService movementService;

    @Autowired
    private OssTemplate ossTemplate;

    @Reference
    private UserInfoService userInfoService;

    @Reference
    private CommentService commentService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Autowired
    private MovementMQSend movementMQSend;

    // 发布动态
    public void saveMovement(Movement movement, MultipartFile[] imageContent) throws IOException {
        // 1.获取用户id
        Long userId = UserHolder.get().getId();
        // 2.oss上传
        List<String> medias = new ArrayList<>();
        if (ArrayUtil.isNotEmpty(imageContent)) {
            for (MultipartFile file : imageContent) {
                String picUrl = ossTemplate.upload(file.getOriginalFilename(), file.getInputStream());
                medias.add(picUrl);
            }
        }
        // 3.封装movement对象
        movement.setId(ObjectId.get()); // 指定动态id
        movement.setMedias(medias); // 图片
        movement.setUserId(userId); // 发布人id
        movement.setState(0); // 审核状态
        movement.setCreated(System.currentTimeMillis()); // 发布时间
        movement.setSeeType(1); // 目前1.0V还未实现
        // 4.调用rpc发布动态
        movementService.saveMovement(movement);

        // 发送mq消息（审核）
        rocketMQTemplate.convertAndSend("tanhua-movement", movement.getId().toHexString());

        // 发送mq消息（推荐）
        movementMQSend.sendMovement(userId, movement.getId().toHexString(), MovementMQSend.MOVEMENT_PUBLISH);

    }

    // 查看我的动态
    public ResponseEntity findMyMovementByPage(Long userId, Integer pageNum, Integer pageSize) {
        // 1.调用prc查询
        PageBeanVo pageBeanVo = movementService.findMyMovementByPage(userId, pageNum, pageSize);
        // 2.取出动态详情
        List<Movement> movementList = (List<Movement>) pageBeanVo.getItems();
        // 3.封装vo
        List<MovementVo> volist = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(movementList)) {
            for (Movement movement : movementList) {
                // 创建vo
                MovementVo vo = new MovementVo();
                // 设置用户信息
                UserInfo userInfo = userInfoService.findByUserId(userId);
                vo.setUserInfo(userInfo);
                // 设置动态信息
                vo.setMovement(movement);
                // 动态获取是否点赞操作
                if (stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.MOVEMENT_LIKE, userId, movement.getId()))) {
                    vo.setHasLiked(1);
                }

                // 将vo设置到集合中
                volist.add(vo);
            }
        }

        // 4.将vo重置到分页对象中
        pageBeanVo.setItems(volist);

        // 5.返回分页对象
        return ResponseEntity.ok(pageBeanVo);

    }

    // 查看好友动态
    public ResponseEntity findFriendMovementByPage(Integer pageNum, Integer pageSize) {
        // 1.获取用户id
        Long userId = UserHolder.get().getId();
        // 2.调用rpc查询
        PageBeanVo pageBeanVo = movementService.findFriendMovementByPage(userId, pageNum, pageSize);
        // 3.取出动态详情集合
        List<Movement> movementList = (List<Movement>) pageBeanVo.getItems();
        // 4.遍历封装vo
        List<MovementVo> voList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(movementList)) {
            for (Movement movement : movementList) {
                // 创建vo
                MovementVo vo = new MovementVo();
                // 设置用户信息
                UserInfo userInfo = userInfoService.findByUserId(movement.getUserId());// 动态发布人id（好友）
                vo.setUserInfo(userInfo);
                // 设置动态详情
                vo.setMovement(movement);

                // 动态获取是否点赞操作
                if (stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.MOVEMENT_LIKE, userId, movement.getId()))) {
                    vo.setHasLiked(1);
                }
                // 设置vo集合中
                voList.add(vo);
            }
        }
        // 5.将vo重置到分页对象
        pageBeanVo.setItems(voList);

        // 6.返回分页对象
        return ResponseEntity.ok(pageBeanVo);
    }

    // 查看推荐动态
    public ResponseEntity findRecommendMovementByPage(Integer pageNum, Integer pageSize) {
        // 1.获取userId
        Long userId = UserHolder.get().getId();
        // 2.调用rpc查询推荐动态详情
        PageBeanVo pageBeanVo = movementService.findRecommendMovementByPage(userId, pageNum, pageSize);
        // 3.获取动态详情集合
        List<Movement> movementList = (List<Movement>) pageBeanVo.getItems();
        // 4.封装vo
        List<MovementVo> voList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(movementList)) {
            for (Movement movement : movementList) {
                // 创建vo
                MovementVo vo = new MovementVo();

                // 设置userInfo
                UserInfo userInfo = userInfoService.findByUserId(movement.getUserId());// 查询动态发布人信息
                vo.setUserInfo(userInfo);
                // 设置movement
                vo.setMovement(movement);

                // 动态获取是否点赞操作
                if (stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.MOVEMENT_LIKE, userId, movement.getId()))) {
                    vo.setHasLiked(1);
                }

                // 动态获取是否喜欢操作
                if (stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.MOVEMENT_LOVE, userId, movement.getId()))) {
                    vo.setHasLoved(1);
                }

                // 添加到集合中
                voList.add(vo);
            }
        }
        // 5.重置vo到pageBeanVo中
        pageBeanVo.setItems(voList);
        // 6.返回分页对象
        return ResponseEntity.ok(pageBeanVo);
    }

    // 动态点赞
    public ResponseEntity saveMovementCommentLike(String movementId) {
        // 1.获取userId
        Long userId = UserHolder.get().getId();
        // 2.封装comment对象
        Comment comment = new Comment();
        comment.setCreated(System.currentTimeMillis());// 点赞时间
        comment.setCommentType(1); // 操作类型
        comment.setPublishId(new ObjectId(movementId)); // 动态id
        // 动态发布人id
        Movement movement = movementService.findMovementById(comment.getPublishId());
        comment.setPublishUserId(movement.getUserId());
        comment.setUserId(userId); // 登录人id
        // 3.调用rpc完成点赞
        Integer likeCount = commentService.saveComment(comment);
        // 4.向redis中存储点赞标记  格式：movement_like:userId_movementId
        stringRedisTemplate.opsForValue().set(StrUtil.format(ConstantUtil.MOVEMENT_LIKE, userId, movementId), "1");

        // 发送mq消息（推荐）
        movementMQSend.sendMovement(userId, movement.getId().toHexString(), MovementMQSend.MOVEMENT_LIKE);

        // 5.返回点赞次数
        return ResponseEntity.ok(likeCount);

    }

    // 动态取消点赞
    public ResponseEntity removeMovementCommentLike(String movementId) {
        // 1.获取userId
        Long userId = UserHolder.get().getId();
        // 2.调用rpc移出点赞
        Integer likeCount = commentService.removeComment(movementId, userId, 1);
        // 3.从redis中移除点赞标记
        stringRedisTemplate.delete(StrUtil.format(ConstantUtil.MOVEMENT_LIKE, userId, movementId));

        // 发送mq消息（推荐）
        movementMQSend.sendMovement(userId, movementId, MovementMQSend.MOVEMENT_DISLIKE);
        // 4.返回点赞次数
        return ResponseEntity.ok(likeCount);
    }

    // 动态喜欢
    public ResponseEntity saveMovementCommentLove(String movementId) {
        // 1.获取userId
        Long userId = UserHolder.get().getId();
        // 2.封装comment对象
        Comment comment = new Comment();
        comment.setCreated(System.currentTimeMillis());// 点赞时间
        comment.setCommentType(3); // 操作类型
        comment.setPublishId(new ObjectId(movementId)); // 动态id
        // 动态发布人id
        Movement movement = movementService.findMovementById(comment.getPublishId());
        comment.setPublishUserId(movement.getUserId());
        comment.setUserId(userId); // 登录人id
        // 3.调用rpc喜欢
        Integer loveCount = commentService.saveComment(comment);
        // 4.向redis中存储喜欢标记
        stringRedisTemplate.opsForValue().set(StrUtil.format(ConstantUtil.MOVEMENT_LOVE, userId, movementId), "1");

        // 发送mq消息（推荐）
        movementMQSend.sendMovement(userId, movement.getId().toHexString(), MovementMQSend.MOVEMENT_LOVE);
        // 5.返回喜欢次数
        return ResponseEntity.ok(loveCount);
    }

    // 动态取消喜欢
    public ResponseEntity removeMovementCommentLove(String movementId) {
        // 1.获取userId
        Long userId = UserHolder.get().getId();
        // 2.调用rpc取消喜欢
        Integer loveCount = commentService.removeComment(movementId, userId, 3);
        // 3.从人redis中移除标记
        stringRedisTemplate.delete(StrUtil.format(ConstantUtil.MOVEMENT_LOVE, userId, movementId));

        // 发送mq消息（推荐）
        movementMQSend.sendMovement(userId, movementId, MovementMQSend.MOVEMENT_DISLOVE);
        // 4.返回操作次数
        return ResponseEntity.ok(loveCount);
    }

    // 单条动态
    public ResponseEntity findMovementVoById(String movementId) {
        // 1.调用rpc查询动态详情
        Movement movement = movementService.findMovementById(new ObjectId(movementId));
        // 2.封装movementVo
        MovementVo movementVo = new MovementVo();
        // 设置userInfo
        UserInfo userInfo = userInfoService.findByUserId(movement.getUserId());
        movementVo.setUserInfo(userInfo);
        // 设置movement
        movementVo.setMovement(movement);
        // 发送mq消息（推荐）
        movementMQSend.sendMovement(UserHolder.get().getId(), movement.getId().toHexString(), MovementMQSend.MOVEMENT_BROWSE);

        // 3.返回结果
        return ResponseEntity.ok(movementVo);
    }

    // 评论列表
    public ResponseEntity findCommentVoByMovementId(String movementId, Integer pageNum, Integer pageSize) {
        // 1.调用rpc查询评论列表
        PageBeanVo pageBeanVo = commentService.findCommentByPage(movementId, 2, pageNum, pageSize);
        // 2.封装commentVo
        List<CommentVo> voList = new ArrayList<>();
        // 2-1 取出comment列表
        List<Comment> commentList = (List<Comment>) pageBeanVo.getItems();
        if (CollectionUtil.isNotEmpty(commentList)) {
            for (Comment comment : commentList) {
                // 创建vo
                CommentVo commentVo = new CommentVo();
                // 设置userInfo
                UserInfo userInfo = userInfoService.findByUserId(comment.getUserId());
                commentVo.setAvatar(userInfo.getAvatar()); // 头像
                commentVo.setNickname(userInfo.getNickname()); // 昵称
                // 设置comment
                commentVo.setId(comment.getPublishId().toString()); // 评论id
                commentVo.setContent(comment.getContent()); // 评论内容
                commentVo.setCreateDate(DateUtil.formatDateTime(new Date(comment.getCreated()))); // 评论时间 2021-06-16 12:12:15

                // 添加到集合中
                voList.add(commentVo);
            }
        }
        // 3.重置vo到分页对象
        pageBeanVo.setItems(voList);

        // 4.返回分页对象
        return ResponseEntity.ok(pageBeanVo);
    }

    // 发表评论
    public void saveMovementComment(String movementId, String content) {
        // 1.获取登录userId
        Long userId = UserHolder.get().getId();
        // 2.封装comment
        Comment comment = new Comment();
        comment.setCreated(System.currentTimeMillis()); // 评论时间
        comment.setPublishId(new ObjectId(movementId)); // 评论id
        comment.setCommentType(2); // 操作类型
        comment.setUserId(userId); // 评论人id
        Movement movement = movementService.findMovementById(new ObjectId(movementId));
        comment.setPublishUserId(movement.getUserId());// 动态发布人id
        comment.setContent(content); // 评论内容

        // 发送mq消息（推荐）
        movementMQSend.sendMovement(userId, movement.getId().toHexString(), MovementMQSend.MOVEMENT_COMMENT);
        // 3.调用rpc保存
        commentService.saveComment(comment);
    }
}
